package org.bud.excel.expot.support;

import org.bud.data.bit.ask.FmtAsk;
import org.bud.data.bit.fmt.BaseFmtData;
import org.bud.data.bit.fmt.FmtType;
import org.bud.data.support.AskSupport;
import org.bud.data.support.BaseQueryDataHandler;
import org.bud.excel.expot.bit.ExcelValueInfo;
import org.bud.excel.expot.fmt.*;
import org.bud.util.bit.Funcs;
import org.bud.util.bit.Objects;

import java.util.*;
import java.util.function.Supplier;

/**
 * @author shaun
 * @date 2024/7/18
 * @instruction
 */
public class QueryDataExcelHandler extends BaseQueryDataHandler {
    private final List<FmtAsk> askList = new ArrayList<>();
    private static final Map<FmtType, BaseFmtData<?>> fmtMatch = new HashMap<>();
    static {
        fmtMatch.put(FmtType.STRING, new ExcelStringFmt());
        fmtMatch.put(FmtType.DOUBLE, new ExcelDoubleFmt());
        fmtMatch.put(FmtType.INT,new ExcelIntFmt());
    }
    @Override
    public <Z> Supplier<ExcelValueInfo> format(Z data, Integer i, String key, boolean fmt){
        ExcelFmtAsk askFain = ExcelFmtAsk.emtpy();
        if(fmt){
            for(FmtAsk ask : askList){
                if(Funcs.getOrThrow(() -> ask.getCheck().check(data,key))){
                    if(ask instanceof ExcelFmtAsk){
                        askFain = (ExcelFmtAsk)ask;
                    }
                }
            }
        }
        final ExcelFmtAsk askFainFinal = askFain;
        BaseFmtData<?> fmtData = fmtMatch.get(askFainFinal.getType());
        return () ->
            ExcelValueInfo.builder()
                .value(Funcs.getOrThrow(() -> fmtData.fain(
                        Objects.getValue(data,key),key,askFainFinal)))
                .format(Optional.ofNullable(askFainFinal.getFormat())
                        .orElseGet(() -> ((ExcelFormat)fmtData).format()))
                .fmtType(askFainFinal.getType())
                .defaultValueSupplier(askFainFinal.getDefaultValueSupplier())
                .index(i)
                .build();
    }

    @Override
    public void doSupport(AskSupport support){
        if(support == null){
            return;
        }
        List<FmtAsk> asks = new ArrayList<>();
        support.adderAsk(asks);
        askList.addAll(asks);
    }

}
